package com.fr.base.core;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class UUID
  implements Serializable, Comparable
{
  private static final long serialVersionUID = -4856846361193249489L;
  private final long mostSigBits;
  private final long leastSigBits;
  private transient int version = -1;
  private transient int variant = -1;
  private volatile transient long timestamp = -1L;
  private transient int sequence = -1;
  private transient long node = -1L;
  private transient int hashCode = -1;
  private static volatile SecureRandom numberGenerator = null;

  private UUID(byte[] paramArrayOfByte)
  {
    long l1 = 0L;
    long l2 = 0L;
    for (int i = 0; i < 8; ++i)
      l1 = l1 << 8 | paramArrayOfByte[i] & 0xFF;
    for (i = 8; i < 16; ++i)
      l2 = l2 << 8 | paramArrayOfByte[i] & 0xFF;
    this.mostSigBits = l1;
    this.leastSigBits = l2;
  }

  public UUID(long paramLong1, long paramLong2)
  {
    this.mostSigBits = paramLong1;
    this.leastSigBits = paramLong2;
  }

  public static UUID randomUUID()
  {
    SecureRandom localSecureRandom = numberGenerator;
    if (localSecureRandom == null)
      numberGenerator = localSecureRandom = new SecureRandom();
    byte[] arrayOfByte = new byte[16];
    localSecureRandom.nextBytes(arrayOfByte);
    byte[] tmp33_30 = arrayOfByte;
    tmp33_30[6] = (byte)(tmp33_30[6] & 0xF);
    byte[] tmp43_40 = arrayOfByte;
    tmp43_40[6] = (byte)(tmp43_40[6] | 0x40);
    byte[] tmp53_50 = arrayOfByte;
    tmp53_50[8] = (byte)(tmp53_50[8] & 0x3F);
    byte[] tmp63_60 = arrayOfByte;
    tmp63_60[8] = (byte)(tmp63_60[8] | 0x80);
    return new UUID(arrayOfByte);
  }

  public static UUID nameUUIDFromBytes(byte[] paramArrayOfByte)
  {
    MessageDigest localMessageDigest;
    try
    {
      localMessageDigest = MessageDigest.getInstance("MD5");
    }
    catch (NoSuchAlgorithmException localNoSuchAlgorithmException)
    {
      throw new InternalError("MD5 not supported");
    }
    byte[] arrayOfByte = localMessageDigest.digest(paramArrayOfByte);
    byte[] tmp29_26 = arrayOfByte;
    tmp29_26[6] = (byte)(tmp29_26[6] & 0xF);
    byte[] tmp39_36 = arrayOfByte;
    tmp39_36[6] = (byte)(tmp39_36[6] | 0x30);
    byte[] tmp49_46 = arrayOfByte;
    tmp49_46[8] = (byte)(tmp49_46[8] & 0x3F);
    byte[] tmp59_56 = arrayOfByte;
    tmp59_56[8] = (byte)(tmp59_56[8] | 0x80);
    return new UUID(arrayOfByte);
  }

  public static UUID fromString(String paramString)
  {
    String[] arrayOfString = paramString.split("-");
    if (arrayOfString.length != 5)
      throw new IllegalArgumentException("Invalid UUID string: " + paramString);
    for (int i = 0; i < 5; ++i)
      arrayOfString[i] = "0x" + arrayOfString[i];
    long l1 = Long.decode(arrayOfString[0]).longValue();
    l1 <<= 16;
    l1 |= Long.decode(arrayOfString[1]).longValue();
    l1 <<= 16;
    l1 |= Long.decode(arrayOfString[2]).longValue();
    long l2 = Long.decode(arrayOfString[3]).longValue();
    l2 <<= 48;
    l2 |= Long.decode(arrayOfString[4]).longValue();
    return new UUID(l1, l2);
  }

  public long getLeastSignificantBits()
  {
    return this.leastSigBits;
  }

  public long getMostSignificantBits()
  {
    return this.mostSigBits;
  }

  public int version()
  {
    if (this.version < 0)
      this.version = (int)(this.mostSigBits >> 12 & 0xF);
    return this.version;
  }

  public int variant()
  {
    if (this.variant < 0)
      if (this.leastSigBits >>> 63 == 0L)
        this.variant = 0;
      else if (this.leastSigBits >>> 62 == 2L)
        this.variant = 2;
      else
        this.variant = (int)(this.leastSigBits >>> 61);
    return this.variant;
  }

  public long timestamp()
  {
    if (version() != 1)
      throw new UnsupportedOperationException("Not a time-based UUID");
    long l = this.timestamp;
    if (l < 0L)
    {
      l = (this.mostSigBits & 0xFFF) << 48;
      l |= (this.mostSigBits >> 16 & 0xFFFF) << 32;
      l |= this.mostSigBits >>> 32;
      this.timestamp = l;
    }
    return l;
  }

  public int clockSequence()
  {
    if (version() != 1)
      throw new UnsupportedOperationException("Not a time-based UUID");
    if (this.sequence < 0)
      this.sequence = (int)((this.leastSigBits & 0x0) >>> 48);
    return this.sequence;
  }

  public long node()
  {
    if (version() != 1)
      throw new UnsupportedOperationException("Not a time-based UUID");
    if (this.node < 0L)
      this.node = (this.leastSigBits & 0xFFFFFFFF);
    return this.node;
  }

  public String toString()
  {
    return digits(this.mostSigBits >> 32, 8) + "-" + digits(this.mostSigBits >> 16, 4) + "-" + digits(this.mostSigBits, 4) + "-" + digits(this.leastSigBits >> 48, 4) + "-" + digits(this.leastSigBits, 12);
  }

  private static String digits(long paramLong, int paramInt)
  {
    long l = 1L << paramInt * 4;
    return Long.toHexString(l | paramLong & l - 1L).substring(1);
  }

  public int hashCode()
  {
    if (this.hashCode == -1)
      this.hashCode = (int)(this.mostSigBits >> 32 ^ this.mostSigBits ^ this.leastSigBits >> 32 ^ this.leastSigBits);
    return this.hashCode;
  }

  public boolean equals(Object paramObject)
  {
    if (!(paramObject instanceof UUID))
      return false;
    if (((UUID)paramObject).variant() != variant())
      return false;
    UUID localUUID = (UUID)paramObject;
    return ((this.mostSigBits == localUUID.mostSigBits) && (this.leastSigBits == localUUID.leastSigBits));
  }

  public int compareTo(Object paramObject)
  {
    UUID localUUID = (UUID)paramObject;
    return ((this.leastSigBits > localUUID.leastSigBits) ? 1 : (this.leastSigBits < localUUID.leastSigBits) ? -1 : (this.mostSigBits > localUUID.mostSigBits) ? 1 : (this.mostSigBits < localUUID.mostSigBits) ? -1 : 0);
  }

  private void readObject(ObjectInputStream paramObjectInputStream)
    throws IOException, ClassNotFoundException
  {
    paramObjectInputStream.defaultReadObject();
    this.version = -1;
    this.variant = -1;
    this.timestamp = -1L;
    this.sequence = -1;
    this.node = -1L;
    this.hashCode = -1;
  }
}